#include "hal_motor.h"
#include "systick.h"
#include "shell.h"
#include "FreeRTOS.h"
#include "task.h"
#include "hk32c030xx_gpio.h"
#include "FreeRTOSConfig.h"
#include "hal_tty.h"

#define STOP_DELAY_READY_TIMEOUT        (100)

static int8_t motor_work_run_ = 0;
static int8_t motor_ctrl_status_ = MOTOR_STATE_DOWN;
static uint32_t motor_runing_time_  = 0;

static void motor_init() {
	
	GPIO_InitTypeDef motor_out,motor_in;
	RCC_AHBPeriphClockCmd(MOTOR_CTRL_RCU | MOTOR_SEQUENCE_RCU, ENABLE);
	
    motor_out.GPIO_Pin = MOTOR_CTRL_RUN | MOTOR_CTRL_DOWN | MOTOR_CTRL_UP;
    motor_out.GPIO_Mode = GPIO_Mode_OUT;
    motor_out.GPIO_OType = GPIO_OType_PP;
    motor_out.GPIO_Speed = GPIO_Speed_50MHz;
    motor_out.GPIO_PuPd = GPIO_PuPd_NOPULL;
    motor_out.GPIO_Schmit = GPIO_Schmit_Disable;
    GPIO_Init(MOTOR_CTRL_BASE, &motor_out);

	GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN | MOTOR_CTRL_UP);
	GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_DOWN);

	motor_in.GPIO_Pin = MOTOR_SEQUENCE_PIN;
	motor_in.GPIO_Mode = GPIO_Mode_IN;
	motor_in.GPIO_OType = GPIO_OType_PP;
	motor_in.GPIO_Speed = GPIO_Speed_10MHz;
	motor_in.GPIO_PuPd = GPIO_PuPd_NOPULL;
	motor_in.GPIO_Schmit = GPIO_Schmit_Disable;
	
	GPIO_Init(MOTOR_SEQUENCE_BASE, &motor_in);

    motor_work_run_ = 0;
    motor_ctrl_status_ = MOTOR_STATE_DOWN;
}

static int motor_setting(int speed_set,int timeout) {

    return 0;
}

static void motor_ctrl_up() {

    if(motor_work_run_) {
        GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN);
        delay_ms(STOP_DELAY_READY_TIMEOUT);
        motor_work_run_ = 0;
        motor_runing_time_ = xTaskGetTickCount();
    }

//    // if(motor_ctrl_status_ != MOTOR_STATE_UP) {
    GPIO_SetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_UP);
    GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_DOWN);

    motor_ctrl_status_ = MOTOR_STATE_UP;
    // }
    GPIO_SetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN);
}

static void motor_ctrl_down() {

    if(motor_work_run_) {
        GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN);
        delay_ms(STOP_DELAY_READY_TIMEOUT);
        motor_work_run_ = 0;
        motor_runing_time_ = xTaskGetTickCount();
    }

    GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_UP);
    GPIO_SetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_DOWN);
    motor_ctrl_status_ = MOTOR_STATE_DOWN;

	GPIO_SetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN);
}

static void motor_ctrl_run(uint8_t flag) {

    if(motor_work_run_ != flag) {
        if(flag) {
			GPIO_SetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN);
        } else {
			GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_UP);
			GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_DOWN);
			GPIO_ResetBits(MOTOR_CTRL_BASE,MOTOR_CTRL_RUN);
        }
        motor_work_run_ = flag;
        motor_runing_time_ = xTaskGetTickCount();
    }
}

static uint32_t motor_run_time() {
	
    uint32_t current = xTaskGetTickCount();
    uint32_t time = motor_runing_time_ ? (current - motor_runing_time_) : 0;
    return (time / SYSTICK_INT_FREQ);
}

static void motor_get_status(uint8_t *run,uint8_t *state) {
	
    *run = motor_ctrl_status_;
    *state = motor_ctrl_status_;
}

static uint8_t motor_get_phase_sequence(void) {

    if(GPIO_ReadInputDataBit(MOTOR_SEQUENCE_BASE,MOTOR_SEQUENCE_PIN))
        return 1;
	return 0;
}

const motor_ctrl_t g_motor_ = {
    motor_init,
    motor_setting,
    motor_ctrl_up,
    motor_ctrl_down,
    motor_ctrl_run,
    motor_run_time,
    motor_get_status,
	motor_get_phase_sequence,
};

